package com.gopay.bis.service.bank.impl.expay;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.BisPayCheckUtils;
import com.gopay.bis.common.util.constants.BisPayConstants;
import com.gopay.bis.manager.bank.expay.UnionPayAdPayManager;
import com.gopay.bis.service.bank.sms.SmsSupportController;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.SmsConstants;
import com.gopay.common.constants.bank.UnionPayConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.ExPayBaseMessage;
import com.gopay.common.domain.bank.unionpay.expay.UnionPayAdPayMessage;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.ExPayInteractRemoteService;
/**
 * 银联代扣接口
 * @author zhengxue
 *
 */
public class UnionPayAdPayServiceImpl implements ExPayInteractRemoteService {
	@Resource(name = "unionPayAdPayManager")
	private UnionPayAdPayManager unionPayAdPayManager;
	// 短信验证码处理类
	public SmsSupportController smsController;
	
	/**
	 * 认证请求
	 */
	public Result certification(ExPayBaseMessage baseMsg) {
		Result result = new Result(false);
		UnionPayAdPayMessage message = new UnionPayAdPayMessage();
		BeanUtils.copyProperties(baseMsg, message);
		try {
			message = (UnionPayAdPayMessage) unionPayAdPayManager.certification(message);
			if (UnionPayConstants.UNIONPAYADPAY_RESP_CODE.equals(message
					.getRespcode())) {
				// 代扣接口认证成功
				result.setModel("flag", true);
			} else {
				result.setModel("flag", false);
			}
			result.setModel("retMsg", message.getRespmsg());
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6076);
		}
		return result;
	}

	/**
	 * 发送短信验证码请求
	 */
	public Result sendSms(ExPayBaseMessage baseMsg) {
		Result result = new Result(false);
		UnionPayAdPayMessage message = new UnionPayAdPayMessage();
		BeanUtils.copyProperties(baseMsg, message);
		try {
		    Map<String, String> smsRes = smsController.sendSMS(message);
            if (ProcCodeConstants.PROC_CODE_100E6102.equals(smsRes.get("resCode"))) {
                // 短信发送成功
                result.setModel("flag", true);
            } else {
                // 短信发送失败
                result.setModel("flag", false);
            }
            result.setModel("sendCount", smsRes.get("sendCount"));
            result.setModel("retMsg", smsRes.get("retMsg"));
            result.setModel("resCode", smsRes.get("resCode"));
            result.setResultCode(smsRes.get("resCode"));
            result.setSuccess(true);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6077);
		}
		return result;
	}
	
	/**
	 * 验证短信请求
	 */
	public Result checkSms(ExPayBaseMessage baseMsg) {
		Result result = new Result(false);
		UnionPayAdPayMessage message = new UnionPayAdPayMessage();
		BeanUtils.copyProperties(baseMsg, message);
		try {
		    Map<String, String> smsRes = smsController.checkSMS(message);
            if (ProcCodeConstants.PROC_CODE_100E6091.equals(smsRes.get("resCode"))) {
                // 验证通过
                result.setModel("flag", true);               
            } else {
                // 验证失败
                result.setModel("flag", false);
                if(!ProcCodeConstants.PROC_CODE_100E6099.equals(smsRes.get("resCode"))){
                    Map<String, String> freezeRes = smsController.freezeCard(message);
                    if(freezeRes != null)
                        smsRes = freezeRes;
                }
            }
            result.setModel("failCount", smsRes.get("failCount"));
            result.setModel("retMsg", smsRes.get("retMsg"));
            result.setModel("resCode", smsRes.get("resCode"));
            result.setResultCode(smsRes.get("resCode"));
            result.setSuccess(true);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6078);
		}
		return result;
	}
	
	/**
	 * 支付请求
	 */
	public Result payment(ExPayBaseMessage baseMsg) {
		Result result = new Result(false);
//		baseMsg.setBankOrderId("CP" + TransUtil.processOrderIdTo14Digit(baseMsg.getOrderId()));
		UnionPayAdPayMessage message = new UnionPayAdPayMessage();
		BeanUtils.copyProperties(baseMsg, message);
		try {
			message = (UnionPayAdPayMessage) unionPayAdPayManager.payment(message);
			result.setModel("res", message);
			result.setDefaultModel(message.isFlag());
			Map<String, String> param = new HashMap<String, String>();
			if (message.isFlag()
					&& message.getTransStat().equals(
							UnionPayConstants.UNIONPAY_PAY_SUCCESS)) {
				// 验签成功
				param.put("orderId", message.getOrderNo());
				param.put("amt", formatAmt(message.getTransAmt()));
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "00");
				param.put("retCode", "00");
				param.put("retMsg", "验签成功");
				param.put("isFront", String.valueOf(false));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setOrderStatus(true);
			} else {
				// 通知后台地址该订单失败
				param.put("orderId", baseMsg.getOrderId());
				param.put("amt", baseMsg.getAmount().toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "01");
				param.put("retCode", "01");
				param.put("retMsg", "验签失败");
				param.put("isFront", String.valueOf(false));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setOrderStatus(false);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6057);
		}
		return result;
	}
	
	/**
	 * 订单查询
	 */
	public Result queryOrder(ExPayBaseMessage base) {
		Result result = new Result(false);
		UnionPayAdPayMessage message = new UnionPayAdPayMessage();
		BeanUtils.copyProperties(base, message);
		try {
			message = (UnionPayAdPayMessage) unionPayAdPayManager.query(message);
			result.setDefaultModel(message);
			result.setSuccess(true);
			if(BisPayCheckUtils.checkExternalOrderID(base.getOrderId())){
				Map<String, String> param = new HashMap<String, String>();
				String amount = base.getAmount().toString();
				param.put("orderId", base.getOrderId());
				param.put("amount", amount);
				if (message == null) {
					// 查询结果为空
					param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
					param.put("returnMessage", "银行返回对账结果为空");
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					result.setModel("queryResult", param);
					return result;
				}
				if(message.isFlag()){
					//成功处理
					if (UnionPayConstants.UNIONPAY_PAY_SUCCESS.equals(message
							.getTransStat())) {
						param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
						param.put("tradeState", BisPayConstants.TRADESTATE_SUCCESS);
						param.put("returnMessage", "交易成功");
					} else if (UnionPayConstants.UNIONPAY_ADPAY_QUERY_TIMEOUT
							.equals(message.getTransStat())
							|| UnionPayConstants.UNIONPAY_ADPAY_QUERY_DEALING
									.equals(message.getTransStat())
							|| UnionPayConstants.UNIONPAY_ADPAY_QUERY_UNKOWN
									.equals(message.getTransStat())) {
						param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
						param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
						param.put("returnMessage", "银行订单正在处理中");
					} else {
						param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
						param.put("tradeState", BisPayConstants.TRADESTATE_FAIL);
						param.put("returnMessage", "交易失败");
					}
				} else {
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", "银行验签失败");
				}
				result.setModel("queryResult", param);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6058);
		}
		return result;
	}
	
	@Override
	public Result sign(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result verify(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result treatyQuery(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result cancel(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result refund(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}

	public SmsSupportController getSmsController() {
		return smsController;
	}

	public void setSmsController(SmsSupportController smsController) {
		this.smsController = smsController;
	}
	
	protected String formatAmt(String amtStr) {
		amtStr = amtStr.replaceAll("^(0+)", "");  
		
		// 增加校验功能，防止误操作
		if (amtStr.indexOf(".") > -1) {
			return amtStr;
		}

		BigDecimal amt = null;
		try {
			amt = new BigDecimal(amtStr);
		} catch (Exception e) {
			amt = new BigDecimal("0");
		}
		amt = amt.movePointLeft(2);
		return amt.toString();
	}

    @Override
    public Result queryCvn(ExPayBaseMessage baseMsg) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Result queryNeedCert(ExPayBaseMessage baseMsg) {
        // TODO Auto-generated method stub
        return null;
    }
/*	@Override
	public Result refundQuery(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}*/

    @Override
    public Result refundBack(ExPayBaseMessage baseMsg) {
        // TODO Auto-generated method stub
        return null;
    }
}
